Merge pull request #612 from cantino/commander_agent_can_configure

Commander agent can configure

Andrew Cantino лет %!s(int64=9): %!d(string=назад)
Родитель
Сommit
2ea63f7acb

+ 7 - 0
app/concerns/agent_controller_concern.rb

@@ -23,6 +23,10 @@ module AgentControllerConcern
23 23
           errors.add(:base, "#{target.name} cannot be scheduled")
24 24
         end
25 25
       }
26
+    when 'configure'
27
+      if options['configure_options'].nil? || options['configure_options'].keys.length == 0
28
+        errors.add(:base, "The 'configure_options' options hash must be supplied when using the 'configure' action.")
29
+      end
26 30
     when 'enable', 'disable'
27 31
     when nil
28 32
       errors.add(:base, "action must be specified")
@@ -63,6 +67,9 @@ module AgentControllerConcern
63 67
             target.update!(disabled: true)
64 68
             log "Agent '#{target.name}' is disabled"
65 69
           end
70
+        when 'configure'
71
+          target.update!(options: target.options.merge(interpolated['configure_options']))
72
+          log "Agent '#{target.name}' is configured with #{interpolated['configure_options'].inspect}"
66 73
         when ''
67 74
           # Do nothing
68 75
         else

+ 6 - 2
app/models/agents/commander_agent.rb

@@ -5,7 +5,7 @@ module Agents
5 5
     cannot_create_events!
6 6
 
7 7
     description <<-MD
8
-      This agent is triggered by schedule or an incoming event and commands other agents ("targets") to run, disable or enable themselves.
8
+      This agent is triggered by schedule or an incoming event and commands other agents ("targets") to run, disable, configure, or enable themselves.
9 9
 
10 10
       # Action types
11 11
 
@@ -17,12 +17,16 @@ module Agents
17 17
 
18 18
       * `enable`: Target Agents are enabled (if not) when this agent is triggered.
19 19
 
20
+      * `configure`: Target Agents have their options updated with the contents of `configure_options`.
21
+
20 22
       Here's a tip: you can use Liquid templating to dynamically determine the action type.  For example:
21 23
 
22
-      - To create a CommanderAgent that receives an event from WeatherAgent every morning to kick an agent flow that is only useful in a nice weather, try this: `{% if conditions contains 'Sunny' or conditions contains 'Cloudy' %}run{% endif %}`
24
+      - To create a CommanderAgent that receives an event from a WeatherAgent every morning to kick an agent flow that is only useful in a nice weather, try this: `{% if conditions contains 'Sunny' or conditions contains 'Cloudy' %}run{% endif %}`
23 25
 
24 26
       - Likewise, if you have a scheduled agent flow specially crafted for rainy days, try this: `{% if conditions contains 'Rain' %}enable{% else %}disabled{% endif %}`
25 27
 
28
+      - If you want to update a WeatherAgent based on a UserLocationAgent, you could use `'action': 'configure'` and set 'configure_options' to `{ 'location': '{{_location_.latlng}}' }`.
29
+
26 30
       # Targets
27 31
 
28 32
       Select Agents that you want to control from this CommanderAgent.

+ 5 - 1
lib/location.rb

@@ -82,6 +82,10 @@ class Location
82 82
     !present?
83 83
   end
84 84
 
85
+  def latlng
86
+    "#{lat},#{lng}"
87
+  end
88
+
85 89
   private
86 90
 
87 91
   def floatify(value)
@@ -100,7 +104,7 @@ class Location
100 104
 end
101 105
 
102 106
 class LocationDrop
103
-  KEYS = Location.members.map(&:to_s).concat(%w[latitude longitude])
107
+  KEYS = Location.members.map(&:to_s).concat(%w[latitude longitude latlng])
104 108
 
105 109
   def before_method(key)
106 110
     if KEYS.include?(key)

+ 5 - 0
spec/lib/location_spec.rb

@@ -30,6 +30,10 @@ describe Location do
30 30
     expect(location['lat']).to eq 2.0
31 31
   end
32 32
 
33
+  it "has a convencience accessor for combined latitude and longitude" do
34
+    expect(location.latlng).to eq "2.0,3.0"
35
+  end
36
+
33 37
   it "does not allow hash-style assignment" do
34 38
     expect {
35 39
       location[:lat] = 2.0
@@ -60,6 +64,7 @@ describe Location do
60 64
       '{{location.latitude}}' => '2.0',
61 65
       '{{location.lng}}' => '3.0',
62 66
       '{{location.longitude}}' => '3.0',
67
+      '{{location.latlng}}' => '2.0,3.0',
63 68
     }.each { |template, result|
64 69
       expect(Liquid::Template.parse(template).render('location' => location.to_liquid)).to eq(result),
65 70
         "expected #{template.inspect} to expand to #{result.inspect}"

+ 21 - 0
spec/support/shared_examples/agent_controller_concern.rb

@@ -41,6 +41,15 @@ shared_examples_for AgentControllerConcern do
41 41
           expect(agent).to be_valid
42 42
         }
43 43
       end
44
+
45
+      it "should ensure that 'configure_options' exists in options when the action is 'configure'" do
46
+        agent.options['action'] = 'configure'
47
+        expect(agent).not_to be_valid
48
+        agent.options['configure_options'] = {}
49
+        expect(agent).not_to be_valid
50
+        agent.options['configure_options'] = { 'key' => 'value' }
51
+        expect(agent).to be_valid
52
+      end
44 53
     end
45 54
   end
46 55
 
@@ -107,5 +116,17 @@ shared_examples_for AgentControllerConcern do
107 116
       agent.control!
108 117
       expect(agent.control_targets.reload).to all(satisfy { |a| !a.disabled? })
109 118
     end
119
+
120
+    it "should configure targets" do
121
+      agent.options['action'] = 'configure'
122
+      agent.options['configure_options'] = { 'url' => 'http://some-new-url.com/{{"something" | upcase}}' }
123
+      agent.save!
124
+      old_options = agents(:bob_website_agent).options
125
+
126
+      agent.control!
127
+
128
+      expect(agent.control_targets.reload).to all(satisfy { |a| a.options['url'] == 'http://some-new-url.com/SOMETHING' })
129
+      expect(agents(:bob_website_agent).reload.options).to eq(old_options.merge('url' => 'http://some-new-url.com/SOMETHING'))
130
+    end
110 131
   end
111 132
 end